package fr.labri.macchiato.framework.business.service;

import fr.labri.macchiato.framework.business.finder.BusinessEntityFinder;
import fr.labri.macchiato.framework.business.finder.ProductFinder;
import fr.labri.macchiato.framework.business.sparql.SparqlBusinessEntityFinder;
import fr.labri.macchiato.framework.business.sparql.SparqlProductFinder;

/**
 * 
 * Singleton class regrouping all services and their associated repositories
 * 
 * @author Matthieu Foucault
 * 
 */
public class Services {

	private static Services instance;

	/**
	 * @return the singleton's instance
	 */
	public static Services getInstance() {
		if (instance == null)
			instance = new Services();
		return instance;
	}

	private PreferencesService preferencesService;
	private ProjectService projectService;

	private ProductFinder productFinder;
	private ServiceFactory serviceFactory;
	private BusinessEntityService businessEntityService;
	private BusinessEntityFinder businessEntityFinder;

	/**
	 * Default Constructor <br>
	 * Initializes the repositories
	 */
	private Services() {
		productFinder = new SparqlProductFinder();
		businessEntityFinder = new SparqlBusinessEntityFinder();
	}

	/**
	 * @return The {@link PreferencesService}
	 */
	public PreferencesService getPreferencesService() {
		return preferencesService;
	}

	/**
	 * Initializes the {@link ServiceFactory} with the proper concrete factory,
	 * whether the entities have to be stored in the local or session storage
	 * 
	 * @param useLocalStorage
	 */
	public void initializeServiceFactory(boolean useLocalStorage) {
		// TODO : when changing the factory, transfer the data between the
		// repositories, and delete the entities from the original one
		if (useLocalStorage)
			serviceFactory = new PersistedServiceFactory();
		else
			serviceFactory = new TransientServiceFactory();
		preferencesService = serviceFactory.newPreferencesService();
		projectService = serviceFactory.newProjectService(productFinder);
		businessEntityService = serviceFactory.newBusinessEntityService(businessEntityFinder);
	}

	/**
	 * @return the {@link ProjectService}
	 */
	public ProjectService getProjectService() {
		return projectService;
	}

	/**
	 * @return the {@link ProductFinder}
	 */
	public ProductFinder getProductFinder() {
		return productFinder;
	}

	/**
	 * 
	 * @return the {@link BusinessEntityService}
	 */
	public BusinessEntityService getBusinessEntityService() {
		
		return businessEntityService;
	}

}
